/* eslint-disable no-unused-vars */
import React, { useMemo, useRef, forwardRef, useLayoutEffect } from 'react';
import { VariableSizeList as List } from 'react-window';
import AutoSizer from 'react-virtualized-auto-sizer';
import type { DataType } from '../../types/virtual list';

// 虚拟列表组件的属性接口
interface VirtualListProps {
  data: DataType[];                    // 数据源
  defaultItemHeight?: number;          // 默认每项高度
  containerHeight?: number;            // 容器高度
  containerPadding?: number;          // 容器内边距
  headerHeight?: number;              // 表头高度
  onRowClick?: (item: DataType) => void; // 行点击事件
  renderHeader?: () => React.ReactNode;  // 自定义表头渲染
  renderItem?: (item: DataType, style: React.CSSProperties) => React.ReactNode; // 自定义行渲染，包含 style 参数
}

// 定义一个 ref 类型，用于 VariableSizeList
type VariableList = List;

// Internal Row component for measuring
const InnerRow = React.memo(
  ({ index, style, data, onRowClick, renderItem, measureItem }: {
    index: number;
    style: React.CSSProperties;
    data: DataType[];
    onRowClick?: (item: DataType) => void;
    renderItem?: (item: DataType, style: React.CSSProperties) => React.ReactNode; // Pass style to custom render
    measureItem: (index: number, height: number) => void;
  }) => {
    InnerRow.displayName = 'InnerRow';
    const item = data[index];
    const handleClick = () => onRowClick?.(item);
    const rowRef = useRef<HTMLDivElement>(null);

    useLayoutEffect(() => {
      if (rowRef.current) {
        measureItem(index, rowRef.current.getBoundingClientRect().height);
      }
    }, [index, measureItem, item]); // Re-measure if index or item changes

    return (
      <div 
        ref={rowRef} // Attach ref for measurement
        style={{ ...style, cursor: onRowClick ? 'pointer' : 'default' }} 
        className="row"
        onClick={handleClick}
      >
        {renderItem ? (
          // If custom renderItem is provided, use it
          renderItem(item, style) // Pass style to custom renderItem
        ) : (
          // Default row rendering
          <>
            <div className="cell">{item.name}</div>
            <div className="cell price-cell">¥{item.price?.toFixed(2)}</div>
            <div className="cell stock-cell">{item.stock}</div>
            <div className="cell">{item.ingredients}</div>
            <div className="cell">{item.effect}</div>
          </>
        )}
      </div>
    );
  }
);

// Wrap the component with forwardRef
const VirtualList = forwardRef<VariableList, VirtualListProps>((
  {
    data,
    defaultItemHeight = 48,
    containerHeight = 450,
    containerPadding = 20,
    headerHeight = 40,
    onRowClick,
    renderHeader,
    renderItem,
  }, ref // Receive the forwarded ref
) => {
  const itemSizes = useRef<{ [index: number]: number }>({}); // To store measured item sizes
  const listRef = useRef<VariableList>(null); // Internal ref for VariableSizeList

  // Combine the forwarded ref and the internal ref
  React.useImperativeHandle(ref, () => ({ 
      ...listRef.current!, // Expose the List instance methods
      resetAfterIndex: (index: number, shouldForceUpdate?: boolean | undefined) => {
          // Also clear our cached sizes when resetting
          itemSizes.current = {};
          listRef.current?.resetAfterIndex(index, shouldForceUpdate);
      }
  }));

  // Function to get item size (height)
  const getItemSize = (index: number): number => {
    return itemSizes.current[index] || defaultItemHeight; // Use cached size or default
  };

  // Function to measure item height and update the list
  const measureItem = React.useCallback((index: number, height: number) => {
    itemSizes.current[index] = height;
    if (listRef.current) {
      // Important: Only reset if the height has actually changed significantly
      // to avoid infinite render loops.
      if (Math.abs((itemSizes.current[index] || defaultItemHeight) - height) > 1) { // Tolerance for minor variations
           listRef.current.resetAfterIndex(index);
      }
    }
  }, [defaultItemHeight]); // Dependency on defaultItemHeight

  // Pass data and measureItem to the InnerRow component
  const itemData = useMemo(() => ({
    data,
    onRowClick,
    renderItem,
    measureItem
  }), [data, onRowClick, renderItem, measureItem]);

  // Default header rendering
  const defaultHeader = () => (
    <div className="header-row" style={{ 
      fontWeight: 'bold', 
      background: '#f5f5f5', 
      display: 'flex',
      height: headerHeight,
      alignItems: 'center'
    }}>
      <div className="cell">商品名称</div>
      <div className="cell">价格</div>
      <div className="cell">库存</div>
      <div className="cell">原材料</div>
      <div className="cell">功效</div>
      <div className="cell">操作</div>
    </div>
  );

  return (
    <div style={{ padding: containerPadding, height: containerHeight + containerPadding * 2 }}>
      {renderHeader ? renderHeader() : defaultHeader()}
      <div style={{ height: containerHeight }}>
        <AutoSizer>
          {({ height, width }: { height: number; width: number }) => (
            <List
              ref={listRef} // Attach internal ref to the List
              height={height}
              width={width}
              itemCount={data.length}
              itemSize={getItemSize}
              itemKey={(index) => data[index].key}
              itemData={itemData} // Pass itemData to the list
              // onItemsRendered prop is not needed for pagination
            >
              {/* Render our InnerRow component */}
              {({ index, style }) => <InnerRow index={index} style={style} {...itemData} />}
            </List>
          )}
        </AutoSizer>
      </div>
    </div>
  );
});

VirtualList.displayName = 'VirtualList';

export default VirtualList;